# 静态算法：根据基础流量确定路由路径，即使之后发生了流量变化，走的路径依旧不会再发生变化
import numpy as np
from python.lib import json

from topo1 import build_hybrid_topology_shared_tor
from switchesalgo import allocate_switches_with_es

# 创建测试拓扑
G = build_hybrid_topology_shared_tor(num_tor=4)  # 从函数中获取拓扑
print("图的节点G.nodes:", G.nodes())
print("===========输出图的边===========")
print("图的边G.edges:", G.edges())
# 输出每条边的链路容量
# for u, v, data in G.edges(data=True):
#     print(f"链路 {u}→{v} 的容量为：{data['capacity']}")

# 从json文件中读取流量数据
with open('traffic_simulation.json', 'r') as f:
    data = json.load(f)
    # 输出时间为0.12时候的流量需求矩阵作为all_to_all
    for record in data:
        if record['timestamp'] == 0.12:
            all_to_all_list = record['matrix']
            # 转换为矩阵形式
            all_to_all = np.array(all_to_all_list)
            print(all_to_all)
        else:
            # 输出时间为5.19时候的流量需求矩阵作为brust
            if record['timestamp'] == 5.19:
                brust_list = record['matrix']
                brust = np.array(brust_list)
                print(brust)
print("输出的all_to_all流量需求矩阵为:", all_to_all)
print("输出的brust流量需求矩阵为:", brust)
hybrid_flow = brust
print("输出的混合流量需求矩阵为:", hybrid_flow)


# 根据流量需求矩阵获取通信对
all_to_all_dict = {(i, j): all_to_all[i][j] for i in range(all_to_all.shape[0]) for j in range(all_to_all.shape[1])}
hybrid_flow_dict = {(i, j): hybrid_flow[i][j] for i in range(hybrid_flow.shape[0]) for j in
                    range(hybrid_flow.shape[1])}
# 获取all_to_all通信对
T_all_to_all = []
for pair, demand in all_to_all_dict.items():
    # print("pair:",pair)
    # print("demand:",demand)
    if demand > 0:
        T_all_to_all.append(pair)
for pair in T_all_to_all:
    print("pair:", pair)  # 输出的通信对的格式为（1,2），表示ToR1和ToR2

# 将键从 (i, j) 转换为 ("ToR{i}", "ToR{j}")
all_to_all_str_keys = {(f"ToR{i + 1}", f"ToR{j + 1}"): value for (i, j), value in all_to_all_dict.items()}
# print("D_str_keys:",D_str_keys)

# 将值从 numpy.ndarray 转换为浮点数
all_to_all_float_values = {k: float(v) for k, v in all_to_all_str_keys.items()}

# 生成通信对列表
T_all_to_all = [pair for pair, demand in all_to_all_float_values.items() if demand > 0]
print("生成all_to_all通信对列表", T_all_to_all)

# 生成all_to_all+brust通信对
T_hybird_flow = []
for pair, demand in hybrid_flow_dict.items():
    # print("pair:",pair)
    # print("demand:",demand)
    if demand > 0:
        T_hybird_flow.append(pair)
# for pair in T_hybird_flow:
#     print("pair:", pair)  # 输出的通信对的格式为（1,2），表示ToR1和ToR2

# 将键从 (i, j) 转换为 ("ToR{i}", "ToR{j}")
hybrid_str_keys = {(f"ToR{i + 1}", f"ToR{j + 1}"): value for (i, j), value in hybrid_flow_dict.items()}
# print("D_str_keys:",D_str_keys)

# 将值从 numpy.ndarray 转换为浮点数
hybrid_float_values = {k: float(v) for k, v in hybrid_str_keys.items()}

# 生成通信对列表
T_hybird_flow = [pair for pair, demand in hybrid_float_values.items() if demand > 0]
print("生成通信对列表", T_hybird_flow)

# 根据流量需求矩阵获取最优路径
S1,path_t = allocate_switches_with_es(G, T_all_to_all, all_to_all_float_values,{"tor1", "tor2","tor3","tor4"},{"os1", "os2","os3","os4"},18 )
print("\n基本流量的最优路径为:")
for pair, path in path_t.items():
    print(f"{pair} -> {path}，流量需求为{all_to_all_float_values[pair]}")

print("==========混合流量的路径（静态路由）===================")
# 流量变化后，保持原来路径不变，计算任务完成时延
for pair in T_hybird_flow:
    print(f"{pair} -> {path_t[pair]},流量需求为{hybrid_float_values[pair]}")

# 计算延迟
# 计算路径delay
max_delay = 0
for pair in T_hybird_flow:
    # print(f"{pair} -> {path_t[pair]},流量需求为{hybrid_float_values[pair]}")
    # 遍历路径的每一个链路
    min_capacity = 200.0 # 初始化最小链路容量为200，200为光交换机的链路容量
    for i in range(len(path_t[pair])-1):
        u=path_t[pair][i]
        v=path_t[pair][i+1]
        # 获取每条边的链路容量
        capacity = G[u][v]['capacity']
        if capacity < min_capacity:
            min_capacity = capacity
            print(f"链路 {u}-{v} 的容量为 {capacity}")
    max_pair_delay = hybrid_float_values[pair] / min_capacity
    print(f"通信对{pair}最小链路容量为{min_capacity},通信时间为{max_pair_delay}")
    if max_pair_delay > max_delay:
        max_delay = max_pair_delay
print(f"混合流量的最长任务完成时延为{max_delay}")


print("============半更新路由优化算法（只更新路径不更新拓扑 光层固定，电层动态）==============")
should_update_electric_pair = []
for pair in T_hybird_flow:
    is_eletric=True
    # 遍历每个通信对的路径
    for i in range(len(path_t[pair]) - 1):
        u = path_t[pair][i]
        v = path_t[pair][i + 1]
        # 如果边存在且为电链路
        if G.has_edge(u, v) and G[u][v]['type'] == 'electrical':
            print(f"{(u, v)}为电网络路径")
            # is_eletric=False
        elif G.has_edge(u, v) and G[u][v]['type'] == 'optical':
            print(f"{(u, v)}为光网络路径")
            is_eletric=False
            break
        # else:
        #     print(f"{(u, v)}既不是光网络也不是电网络")
        #     is_eletric = False
    # 如果路径上所有的边都是电链路，则将该通信对添加到结果列表中
    if is_eletric:
        should_update_electric_pair.append(pair)
# print(f"通信对{pair}应该更新电链路，原来的最优通信路径为{path_t[pair]}")
print("通信路径为电链路的通信对：",should_update_electric_pair)

# 输出拓扑中的链路类型
# print("拓扑中的链路类型：")
# for u, v in G.edges():
#     if G.has_edge(u, v):
#         print(f"边 {u}-{v} 的类型为 {G[u][v]['type']}")


